class Snake{
    // 蛇头
    head:HTMLDivElement;
    // 蛇身
    bodies: HTMLCollection;
    // 蛇容器
    element: HTMLElement
    constructor(){
        // as xxx：断言
        this.element = document.getElementById('snake') as HTMLElement;
        this.head = this.element.querySelector('div')!;
        this.bodies = this.element.getElementsByTagName('div')! ;
    }
    public get X() : number {
        return this.head.offsetLeft;
    }
    public get Y() : number {
        return this.head.offsetTop
    }
    public set X(v : number) {
        if ( v === this.X) return
        // 如果撞墙，抛出异常，有调用该函数的地方去处理
        if ( v < 0 || v >= 310 ){
            throw new Error('游戏结束')
        }
        // 修改X时。是在修改水平坐标，蛇在左右移动，蛇在向左移动时，不能向有掉头
        if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === v){
            // 如果发生掉头，让蛇向反方向继续移动
            if(v > this.X){
                // 如果v大于旧值x，说明蛇在向右走，此时发生掉头，使蛇继续先左走
                v = this.X - 10
            }else{
                v = this.X + 10
            }
        }

        // 移动身体
        this.moveSnake()
        this.head.style.left = v + 'px';
    }
    public set Y(v : number) {
        if ( v === this.Y) return
        // 如果撞墙，抛出异常，有调用该函数的地方去处理
        if ( v < 0 || v >= 301 ){
            throw new Error('游戏结束')
        }

        // 修改X时。是在修改水平坐标，蛇在左右移动，蛇在向左移动时，不能向有掉头
        if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === v){
            // 如果发生掉头，让蛇向反方向继续移动
            if(v > this.Y){
                // 如果v大于旧值x，说明蛇在向右走，此时发生掉头，使蛇继续先左走
                v = this.Y - 10
            }else{
                v = this.Y + 10
            }
        }


        this.moveSnake()
        this.head.style.top = v + 'px';
    }
    // 蛇增加身体的方法
    addBody(){
        // 创建一个div，并向蛇容器末尾添加
        const elementDiv = document.createElement('div')
        this.element.append(elementDiv)
        this.moveSnake()
    }
    // 移动
    moveSnake(){
        // 遍历蛇整个数组,从数组尾开始，以后一个替代前一个
        for (let index = this.bodies.length - 1; index > 0; index--) {
            let x = (this.bodies[index - 1 ] as HTMLElement).offsetLeft;
            let y = (this.bodies[index - 1] as HTMLElement).offsetTop;
            (this.bodies[index] as HTMLElement).style.top = y + 'px';
            (this.bodies[index] as HTMLElement).style.left = x + 'px';
        }
    }
    // 撞到自己
    checkHeadBody(){
        for (let index = 1; index < this.bodies.length; index++) {
            let bd = this.bodies[index] as HTMLElement;
            if (this.X === bd.offsetLeft && this.Y === bd.offsetTop){
                throw new Error('撞到自己了')
            }
        }
    }
    
    
}
export default Snake